﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Linq;
using System.Text;
using VersionComparer.Base;

namespace VersionComparer.Configuration
{
    public abstract class SettingsBase
    {
        #region consts

        protected const string CATEGORY_ALGORITHM = "Comparison";
        protected const string CATEGORY_GENERAL = "General";
        protected const string CATEGORY_COLORS = "Highlighting";
        #endregion consts

        #region statics
        static SettingsBase()
        {
            foreach (var type in AddInsManager.Current.GetObjectsOfType<SettingsBase>())
            {
                LoadSettings(type);
            }
        }


        private static ConcurrentDictionary<Type, SettingsBase> existingSettings = new ConcurrentDictionary<Type, SettingsBase>();
        protected static T LoadSettings<T>()
            where T: SettingsBase
        {
          
            return LoadSettings ( typeof (T)) as T;
        }

        protected static SettingsBase LoadSettings(Type type)
        {
            SettingsBase newSettings = ServiceLocator.Current.CreateInstance(type , type) as SettingsBase;
            SettingsBase result = ConfigurationHelper.Load<SettingsBase>(newSettings.GetType());
            lock (existingSettings)
            {
                existingSettings.AddOrUpdate(type, result, (x, y) =>
                {
                    return result;
                });
            }
            return result;
        }
        

        public static T GetSettings<T>()
            where T: SettingsBase
        {
            return GetSettings(typeof(T)) as T;
        }
        public static SettingsBase GetSettings(Type type)
        {
            SettingsBase result;
            existingSettings.TryGetValue(type, out result);
            return result;
        }
        #endregion statics

        #region constructors
        protected SettingsBase()
        { }
        #endregion constructors

        #region properties
        [Browsable(false)]
        public abstract string Name
        {
            get;
        }
        [Browsable(false)]
        public bool SomethingChanged
        {
            get;
            set;
        }
        #endregion properties

        #region methods
        public void ResetChanges()
        {
            SomethingChanged = false;
        }
        public void Save()
        {
            Configuration.ConfigurationHelper.Save(this);
        }
        public void Reload()
        {
            SettingsBase newSettings = ConfigurationHelper.Load<SettingsBase>(GetType());
            foreach (var property in newSettings.GetType().GetProperties())
            {
                try
                {
                    if (property.CanRead && property.CanWrite)
                    {
                        property.SetValue(this, property.GetValue(newSettings, null), null);
                    }
                }
                catch
                { 
                    ///ignore errors here 
                }
            }
            SomethingChanged = false;
        }
        #endregion methods

    }
}
